#tool "nuget:?package=xunit.runner.console"
#tool "nuget:?package=OctopusTools"
#tool "nuget:?package=MSBuild.SonarQube.Runner.Tool"
#addin "nuget:?package=Cake.Sonar"

///////////////////////////////////////////////////////////////////////////////
// ARGUMENTS
///////////////////////////////////////////////////////////////////////////////

var target        = Argument("target", "Default");
var configuration = Argument("Configuration", "Release");
var releaseNumber = Argument("releaseNumber", "");

///////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
///////////////////////////////////////////////////////////////////////////////

var isLocalBuild             = !TeamCity.IsRunningOnTeamCity;
var buildFilesFolder         = "BuildCudaServicesScripts";
var solution                 = "BEMachine.sln";
var octopusDeployProjectName = "GA.Cuda";
var octopusDeployServer      = "http://10.120.120.11:8082";
var octopusDeployApiKey      = "API-MBFQMNHSNQE2OQHPSBIQH3MKEY";
var buildFolder              = isLocalBuild ? "./../" : "./";
var sonarLogin               = "admin";
var sonarPassword            = "Calling!3";
var sonarKey                 = "GA.Cuda";
var sonarBranch              = "develop";
var sonarName                = "GA.Cuda";

///////////////////////////////////////////////////////////////////////////////
// SETUP / TEARDOWN
///////////////////////////////////////////////////////////////////////////////

int taskCounter = 0;

///////////////////////////////////////////////////////////////////////////////
// TASK DEFINITIONS
///////////////////////////////////////////////////////////////////////////////

TaskSetup(taskSetupContext => {
  var task = taskSetupContext.Task;
  Information("Executing Task {0} of {1} (Name: {2})", ++taskCounter, Tasks.Count, task.Name);
});

Task("Clean")
  .Does(() => {
    CleanDirectories("./**/bin/" + configuration);
    CleanDirectories("./**/obj/" + configuration);
  });

Task("NuGetRestore")
  .WithCriteria(() => !isLocalBuild)
  .Does(() => NuGetRestore(buildFolder + solution));

Task("SonarBegin")
  .WithCriteria(HasArgument("sonar"))
  .Does(() => {
     SonarBegin(new SonarBeginSettings {
        Url = "http://10.120.120.11:9000",
        Login = sonarLogin,
        Password = sonarPassword,
        Verbose = true,
        Key = sonarKey,
        Branch = sonarBranch,
        Name = sonarName,
     });
  });

Task("Build")
  .IsDependentOn("Clean")
  .IsDependentOn("NuGetRestore")
  .Does(() => MSBuild(buildFolder + solution, new MSBuildSettings {
    NodeReuse = false,
    Configuration = configuration,
    ArgumentCustomization = args => args
      .Append("/clp:ErrorsOnly")
      .Append("/p:RunOctoPack=true")
      .Append("/p:OctoPackPackageVersion=" + releaseNumber)
      .Append("/maxcpucount:4")
  }));

Task("SonarEnd")
  .WithCriteria(HasArgument("sonar"))
  .Does(() => {
     SonarEnd(new SonarEndSettings{
        Login = sonarLogin,
        Password = sonarPassword,
     });
  });

Task("NuGetPush")
  .WithCriteria(() => !isLocalBuild)
  .Does(() => {
    var packages = GetFiles("./**/obj/octopacked/*.nupkg").ToList();
    Information("Packages count {0}", packages.Count());
    packages.ForEach(package => {
      Information(package.FullPath);
      NuGetPush(package, new NuGetPushSettings{
        Source = octopusDeployServer + "/nuget/packages",
        ApiKey = octopusDeployApiKey,
      });
    });
  });



Task("OctoCreateRelease")
  .Does(() => OctoCreateRelease(octopusDeployProjectName, new CreateReleaseSettings {
    Server = octopusDeployServer,
    ApiKey = octopusDeployApiKey,
    ReleaseNumber = releaseNumber,
    ArgumentCustomization = args => args.Append("--packageversion " + releaseNumber)
  }));

Task("Default")
  .IsDependentOn("SonarBegin")
  .IsDependentOn("Build")
  .IsDependentOn("SonarEnd");
Task("PrepareDeploy")
  .IsDependentOn("Default")
  .IsDependentOn("NuGetPush")
  .IsDependentOn("OctoCreateRelease");

RunTarget(target);

private IEnumerable<string> RunGit(string arguments, bool logOutput = true) {
    IEnumerable<string> output;
    var exitCode = StartProcess("git", new ProcessSettings {
        Arguments = arguments,
        Timeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds,
        RedirectStandardOutput = true
    }, out output);

    output = output.ToList();
    if (logOutput) {
        foreach (var line in output) {
            Information(line);
        }
    }

    if (exitCode != 0) {
        Information("Git returned {0}", exitCode);
        throw new Exception("Git Error");
    }

    return output;
}

private string GetGitBranch() {
    IEnumerable<string> output = RunGit("status", false);
    string line = output.FirstOrDefault(s => s.Trim().StartsWith("On branch"));
    if (line == null) {
        line = output.FirstOrDefault(s => s.Trim().StartsWith("HEAD detached "));
        if (line == null) {
            Information("Unable to determine Git Branch");
            foreach (var oline in output) {
                Information(oline);
            }

            throw new Exception("Unable to determine Git Branch");
        }

        return "Detached " + line.Replace("HEAD detached", string.Empty).Trim();
    }

    return line.Replace("On branch", string.Empty).Trim();
}
